<template>
  <a-drawer destroyOnClose :title="title" ref="drawerRef" @close="handleClose" v-model:open="drawer" :width="500">
    <component :is="componentType" v-model:value="formData" :extendAttrConfig="props.extendAttrConfig || {}">
      <template #[key]="data" v-for="(item, key) in $slots">
        <slot :name="key" v-bind="data || {}"></slot>
      </template>
    </component>
  </a-drawer>
</template>
<script lang="ts" setup>
  import { ref, defineExpose, computed, unref, reactive, watch, defineEmits, defineProps } from 'vue';
  import { NodeTypeEnum } from '../enums';
  import { FlowFormModel, PropertyEvent } from '../types';
  import process from './process.vue';
  import start from './start.vue';
  import custom from './custom.vue';
  import decision from './decision.vue';
  import end from './end.vue';
  import fork from './fork.vue';
  import join from './join.vue';
  import task from './task.vue';
  import transition from './transition.vue';
  import subProcess from './subProcess.vue';
  import wfSubProcess from './wfSubProcess.vue';
  const NODE_NAME_LIST = ['wlf:custom', 'wlf:decision', 'wlf:end', 'wlf:fork', 'wlf:join', 'wlf:start', 'wlf:task'] as string[];
  const NODE_NAME_MAP = {
    'wlf:custom': '自定义节点',
    'wlf:decision': '决策节点',
    'wlf:end': '结束节点',
    'wlf:fork': '分支节点',
    'wlf:join': '合并节点',
    'wlf:start': '开始节点',
    'wlf:task': '任务节点',
  };
  // 组件列表
  const COMPONENT_LIST = {
    process,
    start,
    custom,
    decision,
    end,
    fork,
    join,
    task,
    transition,
    subProcess,
    wfSubProcess,
  };
  // 事件
  const emits = defineEmits(['change']);
  // 属性
  const props = defineProps({
    extendAttrConfig: {
      // 扩展属性配置
      type: Object,
    },
    // 扩展的属性key
    extendPropertyKeys: {
      type: Array,
    },
  });
  const drawer = ref(false);
  const drawerRef = ref(null);
  var formData = reactive({} as FlowFormModel);
  // 标题
  const title = computed(() => {
    if (formData.type === 'process') {
      return '设置流程属性';
    } else if (formData.type === 'wlf:transition') {
      return '设置边属性';
    } else if (NODE_NAME_LIST.includes(formData.type)) {
      return `设置${NODE_NAME_MAP[formData.type] || '节点'}属性`;
    } else if (formData.type === 'wlf:subProcess') {
      return '设置子流程属性';
    } else if (formData.type === 'wlf:wfSubProcess') {
      return '设置snaker子流程属性';
    }
    return '';
  });
  // 组件类型
  const componentType = computed(() => {
    const mFormData = formData;
    if (!mFormData || !mFormData.type) return;
    return COMPONENT_LIST[mFormData.type.replace('wlf:', '')];
  });
  // 节点名称
  const nodeName = computed((): NodeTypeEnum => {
    const mFormData = formData;
    if (!mFormData || !mFormData.type) return NodeTypeEnum.ignore;
    return mFormData.type.replace('wlf:', '') as unknown as NodeTypeEnum;
  });
  // 处理emits
  const handleEmits = (propertyName: string, propertyValue: any) => {
    if (propertyValue === undefined) return;
    emits('change', {
      type: unref(nodeName),
      propertyName: propertyName,
      propertyValue: propertyValue,
    } as PropertyEvent);
  };
  // 表单属性keys
  const propertyKeys = [
    // 流程属性
    'name',
    'displayName',
    'expireTime',
    'instanceUrl',
    'instanceNoClass',
    'preInterceptors',
    'postInterceptors',
    // 子流程属性
    'name',
    'displayName',
    'form',
    'version',
    'width',
    'height',
    // 开始节点和结束节点属性
    'name',
    'preInterceptors',
    'postInterceptors',
    // 自定义节点属性
    'name',
    'displayName',
    'clazz',
    'methodName',
    'args',
    'preInterceptors',
    'postInterceptors',
    // 决策节点属性
    'name',
    'expr',
    'handleClass',
    'preInterceptors',
    'postInterceptors',
    // 任务节点属性
    'form',
    'assignee',
    'assignmentHandler',
    'taskType',
    'performType',
    'reminderTime',
    'reminderRepeat',
    'expireTime',
    'autoExecute',
    'callback',
    'width',
    'height',
    'field',
    // 额外扩展的属性
    ...(props.extendPropertyKeys || props.extendAttrConfig?.extendPropertyKeys || []),
  ] as string[];
  // 去重后的key
  const propertyKeysSet = Array.from(new Set(propertyKeys));
  propertyKeysSet.forEach((key: string) => {
    // 监听属性变化
    watch(
      () => formData[key],
      (n) => handleEmits(key, n),
      { deep: true }
    );
  });
  // 显示抽屉
  const show = (args: FlowFormModel) => {
    // 将args的值复制给formData
    const width = args.width ? args.width : args.type === 'wlf:subProcess' ? 500 : 120;
    const height = args.height ? args.height : args.type === 'wlf:subProcess' ? 300 : 80;
    Object.assign(formData, args, { width: Number(width), height: Number(height) });
    drawer.value = true;
  };
  // 抽屉关闭处理
  const handleClose = () => {
    // 清空表单值
    Object.keys(formData).forEach((key: string) => {
      delete formData[key];
    });
  };
  // 导入属性及方法给外部调用
  defineExpose({
    show,
  });
</script>
